home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / xview / hview / hview.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-07-14  |  10.2 KB  |  425 lines

  1. /*
  2.  * hview.c   simple program to display HIPS images   -Brian Tierney
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <strings.h>
  7. #include <math.h>
  8. #include <sys/param.h>
  9. #include <sys/types.h>
  10. #include <xview/xview.h>
  11. #include <xview/panel.h>
  12. #include <xview/textsw.h>
  13. #include <xview/xv_xrect.h>
  14.  
  15. #include <X11/Xlib.h>
  16. #include <X11/Xutil.h>
  17. #include <xview/cms.h>
  18.  
  19. #include "hview_ui.h"
  20.  
  21. #include <hipl_format.h>
  22.  
  23. #define SCROLL_BAR_SIZE 21    /* width of scrollbar */
  24.  
  25. /*
  26.  * Global object definitions.
  27.  */
  28. hview_win_objects *Hview_win;
  29. Attr_attribute INSTANCE;
  30.  
  31. Display  *display;
  32. Visual   *winv;
  33. XID       xid;
  34. Window    mainw;
  35. Xv_Window paintwin;
  36. GC        gc;
  37. int       depth;
  38.  
  39. XImage   *ximage = NULL;
  40.  
  41. char     *myname;
  42. byte     *image_data;        /* original data from file (after 24to8 ) */
  43. byte     *image_map;        /* indices into x-colormap (ximage->data) */
  44.  
  45. int       width, height, im_size;
  46. byte      red[256], green[256], blue[256];
  47. int       numcol;
  48.  
  49. void      disp_img(), cmap_init(), share_proc(), change_mode(), mono_proc();
  50. void      build_cmap(), CreateXImage(), apply_gamma();
  51. byte     *load_file();
  52. u_long   *build_colormap();
  53.  
  54. /* global colormap creation modes */
  55. /* see color.c for an explaination of these flags */
  56. int       noglob = 0, perfect = 0, ncols = 245, rwcolor = 0, mono = 0;
  57. int       use_all = 0, verbose = 2;
  58. int       quantize = 1;
  59.  
  60. /*****************************************************/
  61. main(argc, argv)
  62.     int       argc;
  63.     char    **argv;
  64. {
  65.     XGCValues gcval;
  66.     char     *fname;
  67.  
  68.     Progname = strsave(*argv);
  69.     hipserrlev = HEL_SEVERE;    /* only exit if severe errors */
  70.  
  71.     myname = rindex(argv[0], '/');
  72.     if (!myname)
  73.     myname = argv[0];
  74.     else
  75.     myname++;
  76.  
  77.     if (argc == 2)
  78.     fname = argv[1];
  79.     else
  80.     fname = "<stdin>";
  81.  
  82.     /*
  83.      * Initialize XView.
  84.      */
  85.     xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
  86.     INSTANCE = xv_unique_key();
  87.  
  88.     /*
  89.      * Initialize user interface components. Do NOT edit the object
  90.      * initializations by hand.
  91.      */
  92.     Hview_win = hview_win_objects_initialize(NULL, NULL);
  93.  
  94.     /* set defaults */
  95.     (void) xv_set(Hview_win->slider1, PANEL_VALUE, 12, NULL);
  96.  
  97.     /* set up display, winv, etc for future X calls */
  98.     display = (Display *) xv_get(Hview_win->win, XV_DISPLAY, NULL);
  99.     depth = DisplayPlanes(display, DefaultScreen(display));
  100.  
  101.     if (depth != 8 && depth != 24) {
  102.     fprintf(stderr, "Error: This program requires an 8 or 24-bit color monitor \n");
  103.     exit(0);
  104.     }
  105.     if (depth == 24)
  106.     perfect = 1;        /* will always want perfect colors if an
  107.                  * 24-bit display */
  108.  
  109.     winv = DefaultVisual(display, DefaultScreen(display));
  110.     mainw = (Window) xv_get(Hview_win->win, XV_XID, NULL);
  111.     paintwin = (Xv_Window) canvas_paint_window(Hview_win->can);
  112.     xid = (XID) xv_get(paintwin, XV_XID, NULL);
  113.  
  114.     /* set up a GC with 'reasonable' values */
  115.     gcval.foreground = BlackPixel(display, DefaultScreen(display));
  116.     gcval.background = WhitePixel(display, DefaultScreen(display));
  117.     gcval.clip_mask = None;
  118.     gc = XCreateGC(display, xid, GCForeground | GCBackground |
  119.            GCClipMask, &gcval);
  120.  
  121.     /* initialize the colormap */
  122.  
  123.     image_data = load_file(fname);
  124.     if (image_data == NULL)
  125.     exit(0);
  126.  
  127.  
  128.     /* make colormap */
  129.     cmap_init();
  130.  
  131.     CreateXImage();
  132.  
  133.     image_map = (byte *) malloc(im_size);
  134.     memcpy((char *) image_map, (char *) image_data, im_size);
  135.     build_cmap();
  136.  
  137.     disp_img();
  138.  
  139.     /*
  140.      * Turn control over to XView.
  141.      */
  142.     xv_main_loop(Hview_win->win);
  143.     exit(0);
  144. }
  145.  
  146. /***********************************************************/
  147. void
  148. CreateXImage()
  149. {
  150.     char     *dbuf;
  151.  
  152.     switch (depth) {
  153.     case 8:
  154.     dbuf = (char *) malloc(im_size);
  155.     ximage = XCreateImage(display, winv, depth,
  156.                   ZPixmap, 0, dbuf, width, height, 8, 0);
  157.     if (!ximage) {
  158.         fprintf(stderr, "Error: couldn't create theImage!");
  159.         exit(0);
  160.     }
  161.     break;
  162.  
  163.     /*********************************/
  164. #ifdef LATER            /* someday make work with mono displays */
  165.     case 1:
  166.     dbuf = (char *) malloc(im_size / 8);
  167.     ximage = XCreateImage(display, winv, depth,
  168.                   XYPixmap, 0, dbuf, width, height, 8, 0);
  169.     if (!ximage) {
  170.         fprintf(stderr, "Error: couldn't create theImage!");
  171.         exit(0);
  172.     }
  173.     break;
  174. #endif
  175.  
  176.     /*********************************/
  177.     case 24:
  178.     case 32:
  179.     dbuf = (char *) malloc(im_size * 4);
  180.     ximage = XCreateImage(display, winv, depth,
  181.                   ZPixmap, 0, dbuf, width, height, 32, 0);
  182.     if (!ximage) {
  183.         fprintf(stderr, "Error: couldn't create theImage!");
  184.         exit(0);
  185.     }
  186.     break;
  187.     }
  188. }
  189.  
  190. /*************************************************************/
  191. /*
  192.  * Repaint callback function for `canvas1'.
  193.  */
  194. void
  195. canvas_repaint_proc(canvas, paint_window, display, xid, rects)
  196.     Canvas    canvas;
  197.     Xv_window paint_window;
  198.     Display  *display;
  199.     Window    xid;
  200.     Xv_xrectlist *rects;
  201. {
  202. #ifdef DEBUG
  203.     fputs("hview: canvas_repaint_proc\n", stderr);
  204. #endif
  205.  
  206.     if (ximage != NULL) {
  207.     XPutImage(display, xid, gc, ximage, 0, 0, 0, 0,
  208.           ximage->width, ximage->height);
  209.     }
  210. }
  211.  
  212. /***************************************************************/
  213. imgwin_resize_proc(win, event, arg, type)
  214.     Xv_window win;
  215.     Event    *event;
  216.     Notify_arg arg;
  217.     Notify_event_type type;
  218. {
  219.     int       width, height, ctrl_height;
  220.  
  221. #ifdef DEBUG
  222.     fprintf(stderr, "hview: imgwin_resize_proc: event %d\n", event_id(event));
  223. #endif
  224.     ctrl_height = (int)xv_get(Hview_win->controls1, XV_HEIGHT, NULL);
  225.  
  226.     width = ximage->width + SCROLL_BAR_SIZE;
  227.     height = ximage->height + SCROLL_BAR_SIZE + ctrl_height;
  228.  
  229.     if ((int) xv_get(Hview_win->win, XV_WIDTH) > width)
  230.     xv_set(Hview_win->win, XV_WIDTH, width, NULL);
  231.  
  232.     if ((int) xv_get(Hview_win->win, XV_HEIGHT) > height)
  233.     xv_set(Hview_win->win, XV_HEIGHT, height, NULL);
  234.  
  235.     return;
  236. }
  237.  
  238. /***************************************************/
  239. void
  240. disp_img()
  241. {
  242.     int       win_width, win_height, ctrl_width, ctrl_height;
  243.  
  244.     win_width = MIN((ximage->width + SCROLL_BAR_SIZE), 512);
  245.  
  246.     ctrl_width = (int)xv_get(Hview_win->controls1, XV_WIDTH, NULL);
  247.     ctrl_height = (int)xv_get(Hview_win->controls1, XV_HEIGHT, NULL);
  248.  
  249.     if (win_width < ctrl_width)
  250.     win_width = ctrl_width;
  251.     win_height = MIN((ximage->height + SCROLL_BAR_SIZE + ctrl_height), 512);
  252.  
  253.     xv_set(Hview_win->win,
  254.        XV_WIDTH, win_width,
  255.        XV_HEIGHT, win_height,
  256.        NULL);
  257.  
  258.     xv_set(Hview_win->can,
  259.        CANVAS_AUTO_EXPAND, FALSE,
  260.        CANVAS_AUTO_SHRINK, FALSE,
  261.        OPENWIN_AUTO_CLEAR, TRUE,
  262.        CANVAS_FIXED_IMAGE, FALSE,
  263.        NULL);
  264.     xv_set(Hview_win->can,
  265.        CANVAS_WIDTH, ximage->width,
  266.        CANVAS_HEIGHT, ximage->height,
  267.        NULL);
  268.  
  269.     canvas_repaint_proc(Hview_win->can, paintwin, display, xid, NULL);
  270. }
  271.  
  272. /***************************************************/
  273. byte     *
  274. load_file(fname)
  275.     char     *fname;
  276. {
  277.     FILE     *fp;
  278.     struct header hd;
  279.     byte     *image, *outbuf;
  280.     int       i;
  281.     byte     *pr, *pg, *pb;
  282.  
  283.     if ((int)(fp = hfopenr(fname)) == -1) {
  284.         fprintf(stderr, "\n error opening file %s \n\n", fname);
  285.     return (NULL);
  286.     }
  287.  
  288.     /* read in HIPS header */
  289.     if (fread_header(fp, &hd, (Filename) fname) == HIPS_ERROR) {
  290.     XBell(display, 0);
  291.     fclose(fp);
  292.     return (NULL);
  293.     }
  294.     if (hd.pixel_format != PFBYTE && hd.pixel_format != PFRGB) {
  295.     XBell(display, 0);
  296.     fprintf(stderr, "Data type not currently understood.\n");
  297.     return (NULL);
  298.     }
  299.     if (findparam(hd, "cmap") != NULLPAR) {
  300.     getparam(&hd, "cmap", PFBYTE, &numcol, &pr);
  301.     if (numcol % 3)
  302.         perr(HE_MSG, "colormap length not a multiple of 3");
  303.     numcol /= 3;
  304.     pg = pr + numcol;
  305.     pb = pg + numcol;
  306.     fprintf(stderr, "Reading colormap of size %d \n", numcol);
  307.     for (i = 0; i < numcol; i++) {
  308.         red[i] = pr[i];
  309.         green[i] = pg[i];
  310.         blue[i] = pb[i];
  311.     }
  312.     } else {
  313.     /* build rgb arrays for gray scale images */
  314.     for (i = 0; i < 256; i++)
  315.         red[i] = green[i] = blue[i] = i;
  316.     numcol = 256;
  317.     }
  318.  
  319.  
  320.     fprintf(stderr, "Loading image...... \n");
  321.     if (hd.pixel_format == PFRGB)
  322.     im_size = hd.cols * hd.rows * 3;
  323.     else if (hd.pixel_format == PFRGBZ)
  324.     im_size = hd.cols * hd.rows * 4;
  325.     else
  326.     im_size = hd.cols * hd.rows;
  327.  
  328.     image = (byte *) malloc(im_size);
  329.     if (fread(image, im_size, 1, fp) != 1) {
  330.     XBell(display, 0);
  331.     perror("\n error reading data\n");
  332.     return (NULL);
  333.     }
  334.     width = hd.cols;
  335.     height = hd.rows;
  336.     im_size = width * height;
  337.  
  338.     if (hd.pixel_format == PFRGB) {
  339.     outbuf = (byte *) calloc(im_size, sizeof(byte));
  340.  
  341.     if (quantize) {
  342.         Init24to8();
  343.         numcol = Conv24to8(image, outbuf, width, height, ncols, mono,
  344.                    red, green, blue);
  345.     } else {        /* dither */
  346.         numcol = To_8(image, outbuf, width, height, ncols,
  347.               red, green, blue);
  348.         fprintf(stderr, "RGB image dithered to %d colors \n", numcol);
  349.     }
  350.     image = outbuf;
  351.     }
  352.     return (image);
  353. }
  354.  
  355. /**********************************************************************/
  356. void
  357. cmap_init()
  358. {
  359.     int       i;
  360.     Colormap  cmap;
  361.  
  362.     cmap = XDefaultColormap(display, DefaultScreen(display));
  363. }
  364.  
  365. /*************************************************************/
  366. void
  367. build_cmap()
  368. {
  369.     /* sorted map is returned im image_map */
  370.     build_colormap(display, winv, mainw,
  371.            image_map, im_size,
  372.            red, green, blue, numcol,
  373.            noglob, perfect, ncols, mono, use_all, rwcolor,
  374.            verbose, myname);
  375.  
  376.     map_image_to_colors(ximage->data, image_map, im_size);
  377.  
  378. #ifdef DEBUG
  379.     show_colormap(image_data, im_conv);
  380. #endif
  381.     return;
  382. }
  383.  
  384. /*************************************************************/
  385. void
  386. gamma_proc(item, value, event)
  387.     Panel_item item;
  388.     int       value;
  389.     Event    *event;
  390. {
  391.     double    gammaval;
  392.     static double old_gammaval = -1.0;
  393.     int       get_gamma();
  394.  
  395.     gammaval = (double) xv_get(Hview_win->slider1, PANEL_VALUE, NULL) / 10.;
  396.  
  397.     if (gammaval == old_gammaval)
  398.     return;
  399.  
  400.     fprintf(stderr, "hview: performing gamma with value %.2f \n",
  401.         (float) gammaval);
  402.  
  403.     old_gammaval = gammaval;
  404.  
  405.     apply_gamma(gammaval, noglob, perfect, ncols, mono, rwcolor);
  406.  
  407.     map_image_to_colors((byte *) ximage->data, image_map, im_size);
  408.  
  409.     canvas_repaint_proc(Hview_win->can, paintwin, display, xid, NULL);
  410.  
  411.     fprintf(stderr, "Done. \n");
  412. }
  413.  
  414. /*************************************************************/
  415. int
  416. get_gamma(val, gam)
  417.     byte      val;
  418.     double    gam;
  419. {
  420.     double    newval;
  421.  
  422.     newval = 256. * pow((double) val / 256., (double) (1.0 / gam));
  423.     return (MIN((int) (newval + .5), 255));    /* dont allow values > 255 */
  424. }
  425.